package com.kcs.dc.service.logic;

import java.math.BigDecimal;
import java.sql.Connection;
import java.util.ArrayList;
import javax.xml.transform.TransformerException;
import com.kcs.dc.service.bean.request.wsInquiryReqBody;
import com.kcs.dc.service.bean.request.wsInquiryReqHeader;
import com.kcs.dc.service.bean.request.wsInquiryRequest;
import com.kcs.dc.service.bean.response.wsInquiryResBody;
import com.kcs.dc.service.bean.response.wsInquiryResHeader;
import com.kcs.dc.service.bean.response.wsInquiryResponse;
import com.kcs.dc.service.dao.wsDealCenterDAO;
import com.kcs.dc.service.dao.wsRetAdModel;
import com.kcs.dc.service.utils.LogToDB;
import com.kcs.common.utils.ConnectionUtils;
import com.kcs.common.utils.Constant;
import com.kcs.common.utils.ConstantMessage;
import com.kcs.common.utils.LogWriter;
import com.kcs.common.utils.PropertySet;
import com.kcs.common.utils.PropsUtils;
import com.kcs.common.utils.XmlUtils;
import com.kcs.common.utils.commonUtils;


public class inquiryGenerateBL extends generateResponse{
	
	private int ser_req_id = 0;
	wsDealCenterDAO dao = null;
	
 
    public inquiryGenerateBL() {
    	dao = new wsDealCenterDAO();		
	}

	public wsInquiryResponse generateResponse(wsInquiryRequest request) {
    	

    	LogWriter.info("<=====================================================>", Constant.LOGGER_WEBSERVICE);
    	LogWriter.info("=====Start here : call wsInquiry=====", Constant.LOGGER_WEBSERVICE);
  
        wsInquiryReqHeader reqHeader = request.getHeader();
        wsInquiryReqBody reqBody = request.getBody();
        
        String xmlrequest = "";
        wsInquiryResBody[] responseBody = null;
        
        ArrayList<String> dealList = new ArrayList<String>();
        
        Connection retConn = null;
        Connection dcConn = null;       
        
        try {
        	// -- Get connection 2 system.
        	retConn = getConnectionRETAD();
        	dcConn = getConnectionDealCenter();  
  	
        	//--log request
        	xmlrequest = genRequestXML(reqHeader, reqBody);
        	LogWriter.info("=====XML Request : " + xmlrequest, Constant.LOGGER_WEBSERVICE);
        	
        	wsInquiryResponse resChkHd = basicCheckHeader(dcConn, reqHeader, reqBody);
        	if(resChkHd == null){
        		// Check input ccy,buy_sell
        		wsInquiryResponse resChkBd = basicCheckBody(dcConn, reqBody, reqHeader);
        		if (resChkBd == null){
        			
        			// Check connection of RET-AD
        			if (retConn == null){
        				LogWriter.error(PropsUtils.getMessage(Constant.PROP_MESSAGE, ConstantMessage.ERR_CONN_RETAD), Constant.LOGGER_WEBSERVICE);
        	            return genereateErrorResponse(dcConn, reqHeader, ConstantMessage.ERR_CONN_RETAD, 
        	           		 PropsUtils.getMessage(Constant.PROP_MESSAGE, ConstantMessage.ERR_CONN_RETAD));
        			}else{
        				// Case : Input deal_id
                		if (!isNullOrBlankString(reqBody.getDealId())){
                			/*LogWriter.info("=====Input deal_id and prepare get Ret-Ad.=====", Constant.LOGGER_WEBSERVICE);*/       			
                	    	dealList.add(reqBody.getDealId());	        		
    						
                		}                		
                		
                		responseBody = prepareAndGetRETAD(retConn, dcConn, dealList,
														reqBody.getCifNumber(), 
														reqBody.getCcy1(),
														reqBody.getBuySell(),
														reqBody.getValueDate(),
														reqHeader.getSystem());
                		
        			} // End check connection.
        			
        		}else{
    				// have error.
    				return resChkBd;
    			}
        		
        		if (responseBody != null & responseBody.length > 0){ 
        			LogWriter.info("=====Finish process : call wsInquiry=====", Constant.LOGGER_WEBSERVICE);
	        		return generateSuccessResponse(dcConn, reqHeader, responseBody);		        		
        		}
   			
        	 }else{
        		 // have error.
        		 return resChkHd;
        	 }

        	return generateSuccessResponse(dcConn, reqHeader, responseBody);
        	
        } catch (Exception ex) {
        	ex.printStackTrace();
        	LogWriter.error(PropsUtils.getMessage(Constant.PROP_MESSAGE, ConstantMessage.ERR_EXCEPTION) + ": " + ex.getMessage(), Constant.LOGGER_WEBSERVICE);
        	return genereateErrorResponse(dcConn, reqHeader, ConstantMessage.ERR_EXCEPTION, 
	           		 PropsUtils.getMessage(Constant.PROP_MESSAGE, ConstantMessage.ERR_EXCEPTION) +":"+ ex.getMessage());
        } finally{
    		ConnectionUtils.closeConnection(dcConn);
    		ConnectionUtils.closeConnection(retConn);
    	}
    
    }
    
	private wsInquiryResponse basicCheckHeader(Connection dcConn,
			wsInquiryReqHeader reqHeader, wsInquiryReqBody body) throws Exception {
    	
    	try{
    		
	    	// Check Authenticate RequestID. 
	    	boolean exitLogRequest = isAuthenRequest(dcConn, reqHeader.getRequestID(), reqHeader.getSystem(), reqHeader.getServiceID());
	    	
	    	LogWriter.info("=====Insert Log Request into table.=====", Constant.LOGGER_WEBSERVICE);
	     	ser_req_id = LogToDB.logRequest(dcConn, reqHeader.getSystem(), reqHeader.getServiceID(), reqHeader.getRequestID(),
	     			0, body.getDealId(), body.getCifNumber(), body.getCcy1(), body.getBuySell(), body.getValueDate(), 
	     			new BigDecimal(0), "", "");
	     	
	     	LogWriter.info("=====ser_req_log_id : " + ser_req_id , Constant.LOGGER_WEBSERVICE);
	     	
	     	LogWriter.info("=====Prepare basic check header.=====", Constant.LOGGER_WEBSERVICE);
		   	if(!exitLogRequest) {
		   			LogWriter.error(PropsUtils.getMessage(Constant.PROP_MESSAGE, ConstantMessage.ERR_AUTHEN_REQ), Constant.LOGGER_WEBSERVICE);
		            return genereateErrorResponse(dcConn, reqHeader, ConstantMessage.ERR_AUTHEN_REQ, 
		           		 PropsUtils.getMessage(Constant.PROP_MESSAGE, ConstantMessage.ERR_AUTHEN_REQ));
		     }
		   	 
	    	 // Check Header input.
		   	 if(!isHeaderValid(reqHeader.getSystem(), reqHeader.getServiceID(), reqHeader.getRequestID())) {
		   		 	LogWriter.error(PropsUtils.getMessage(Constant.PROP_MESSAGE, ConstantMessage.ERR_REQH_BLANK), Constant.LOGGER_WEBSERVICE);
		            return genereateErrorResponse(dcConn, reqHeader, ConstantMessage.ERR_REQH_BLANK, 
		           		 PropsUtils.getMessage(Constant.PROP_MESSAGE, ConstantMessage.ERR_REQH_BLANK));
		      }
		   	 
		   	 // Check Authenticate system. 
		   	 if(!isAuthenSystem(dcConn, reqHeader.getSystem(), reqHeader.getServiceID())) {
		   		 	LogWriter.error(PropsUtils.getMessage(Constant.PROP_MESSAGE, ConstantMessage.ERR_AUTHEN_SYS), Constant.LOGGER_WEBSERVICE);
		            return genereateErrorResponse(dcConn, reqHeader, ConstantMessage.ERR_AUTHEN_SYS, 
		           		 PropsUtils.getMessage(Constant.PROP_MESSAGE, ConstantMessage.ERR_AUTHEN_SYS));
		      }
    	}catch(Exception e){
    		throw new Exception();
    	}
   	 
	   	 return null;
    }
    
    private wsInquiryResponse basicCheckBody(Connection dcConn, wsInquiryReqBody reqBody, wsInquiryReqHeader reqHeader) throws Exception{
    	
    	LogWriter.info("=====Prepare basic check body.=====", Constant.LOGGER_WEBSERVICE);   	
    	
   	 	 // Check Body input.
    	if (isNullOrBlankString(reqBody.getDealId()) &&
    			isNullOrBlankString(reqBody.getCifNumber()) &&
    			isNullOrBlankString(reqBody.getCcy1()) &&
    			isNullOrBlankString(reqBody.getBuySell())){
    		LogWriter.error(PropsUtils.getMessage(Constant.PROP_MESSAGE, ConstantMessage.ERR_DEAL_CIF), Constant.LOGGER_WEBSERVICE);
            return genereateErrorResponse(dcConn, reqHeader, ConstantMessage.ERR_DEAL_CIF, 
           		 PropsUtils.getMessage(Constant.PROP_MESSAGE, ConstantMessage.ERR_DEAL_CIF));
    	}
    	
	   	if(!isBodyValid(reqBody.getCcy1(), reqBody.getBuySell())) {
	   			LogWriter.error(PropsUtils.getMessage(Constant.PROP_MESSAGE, ConstantMessage.ERR_REQB_INQ_BLANK), Constant.LOGGER_WEBSERVICE);
	            return genereateErrorResponse(dcConn, reqHeader, ConstantMessage.ERR_REQB_INQ_BLANK, 
	           		 PropsUtils.getMessage(Constant.PROP_MESSAGE, ConstantMessage.ERR_REQB_INQ_BLANK));
	     }
	   	 	   	 
	   	 return null;
   }
    
    private boolean isBodyValid(String ccy, String buy_sell) {
		
		boolean somethingNull = (isNullOrBlankString(ccy) || 
								 isNullOrBlankString(buy_sell));

		if (somethingNull) return false;
							
		return true;
		
	}

    private String genRequestXML(wsInquiryReqHeader header, wsInquiryReqBody body){
    	
    	String xmlRequest = null;
    	
    	PropertySet reqH = new PropertySet();
    	reqH.setType("wsInquiryReqHeader");
    	
    	PropertySet modelH = new PropertySet();
    	modelH.setProperty("system", header.getSystem());
    	modelH.setProperty("serviceID", header.getServiceID());
    	modelH.setProperty("requestID", header.getRequestID());
    	reqH.addChild(modelH);
    	
    	PropertySet reqB = new PropertySet();
    	reqB.setType("wsInquiryReqBody");
    	
    	PropertySet modelB = new PropertySet();
    	modelB.setProperty("cifNumber", body.getCifNumber());
    	modelB.setProperty("dealID", body.getDealId());
    	modelB.setProperty("ccy1", body.getCcy1());
    	modelB.setProperty("buySell", body.getBuySell());
    	modelB.setProperty("valueDate", body.getValueDate());
    	reqB.addChild(modelB);
    	
    	PropertySet req = new PropertySet();
    	req.addChild(reqH);
    	req.addChild(reqB);
    	
    	
		try {
			xmlRequest = XmlUtils.propertySetToXmlString(req);
		} catch (TransformerException e) {
			// TODO Auto-generated catch block
			xmlRequest = "";
			LogWriter.error(PropsUtils.getMessage(Constant.PROP_MESSAGE, ConstantMessage.ERR_EXCEPTION) + ": " + e.getMessage(), Constant.LOGGER_WEBSERVICE);
		}
    	
		return xmlRequest;
    }
    
    private String genResponseXML(wsInquiryResHeader header, wsInquiryResBody[] body){
    	
    	String xmlRequest = null;
    	
    	PropertySet reqH = new PropertySet();
    	reqH.setType("wsInquiryResHeader");
	
    	PropertySet modelH = new PropertySet();
    	modelH.setProperty("system", header.getSystem());
    	modelH.setProperty("serviceID", header.getServiceID());
    	modelH.setProperty("requestID", header.getRequestID());
    	modelH.setProperty("respCode", header.getRespCode());
    	modelH.setProperty("respDesc", header.getRespDesc());
    	modelH.setProperty("respTime", header.getRespTime());
    	modelH.setProperty("numberOfRec", String.valueOf(header.getNumberOfRec()));
    	reqH.addChild(modelH);
    	   	
    	PropertySet reqB = new PropertySet();
    	reqB.setType("wsInquiryResBody");   	
    	for (int i = 0; i < body.length; i++) {
    		PropertySet modelB = new PropertySet();
    		modelB.setProperty("Row",  String.valueOf(i+1));
    		modelB.setProperty("dealID", body[i].getDealId());
    		modelB.setProperty("parentID", body[i].getParentId());
    		modelB.setProperty("cifNumber", body[i].getCifNumber());
    		modelB.setProperty("custName", body[i].getCustName());
    		modelB.setProperty("transType", body[i].getTransType());
    		modelB.setProperty("buySell", body[i].getBuySell());
    		modelB.setProperty("dealDate", body[i].getDealDate());
    		modelB.setProperty("valueDate", body[i].getValueDate());
    		modelB.setProperty("ccy1", body[i].getCcy1());
    		modelB.setProperty("dealAmt1", String.valueOf(body[i].getDealAmt1()));
    		modelB.setProperty("exchRate", String.valueOf(body[i].getExchRate()));
    		modelB.setProperty("ccy2", body[i].getCcy2());
    		modelB.setProperty("equiAmt", String.valueOf(body[i].getEquiAmt()));
    		modelB.setProperty("outstdAmt", String.valueOf(body[i].getOutsdAmt()));
    		modelB.setProperty("instrumentType", body[i].getInstrumentType());
    		modelB.setProperty("branch", body[i].getBranch());
    		modelB.setProperty("comments", body[i].getComments());
    		modelB.setProperty("makerID", body[i].getMakerId());
    		modelB.setProperty("ibcCode", body[i].getIbcCode());
    		modelB.setProperty("documentType", body[i].getDocumentType());
    		modelB.setProperty("lastModifyDate", body[i].getLastModifyDate());
        	
        	reqB.addChild(modelB);
		}
    	
   	
    	PropertySet req = new PropertySet();
    	req.addChild(reqH);
    	req.addChild(reqB);
    	
    	
		try {
			xmlRequest = XmlUtils.propertySetToXmlString(req);
		} catch (TransformerException e) {
			// TODO Auto-generated catch block
			xmlRequest = "";
			LogWriter.error(PropsUtils.getMessage(Constant.PROP_MESSAGE, ConstantMessage.ERR_EXCEPTION) + ": " + e.getMessage(), Constant.LOGGER_WEBSERVICE);
		}
    	
		return xmlRequest;
    }
    
 	private wsInquiryResBody[] prepareAndGetRETAD(Connection retConn, Connection dcConn, ArrayList<String> dealList,
			String cif_id, String ccy, String buy_sell, String value_date, String mod_user)
			throws Exception {
 		   	
    	wsInquiryResBody[] response = null;
    	
    	try{  
    		
    		// Check value_date by Deal or CIF.
    		if (dealList.size() > 0){
    			value_date = commonUtils.formatDate(commonUtils.getCurrentDate(), commonUtils.yyyymmdd);
    		}else{
		    	if (!isNullOrBlankString(value_date)){
		    		value_date = commonUtils.convertFormatDate(value_date, commonUtils.ddmmyyyywithslash, commonUtils.yyyymmdd);
		    	}else{
		    		value_date = commonUtils.formatDate(commonUtils.getCurrentDate(), commonUtils.yyyymmdd);
		    	}
    		}
	    	
    		// Prepare query from RET-AD  	
	    	wsRetAdModel[] RetadModel = dao.getDataRetAD(cif_id, ccy, buy_sell, value_date, dealList, retConn);
	    	
	    	if(RetadModel != null){
	    		
	    		for (int i = 0; i < RetadModel.length; i++) {
	    			
	    			/*Call Store all Insert And Update.*/
	    			LogWriter.debug("Prepare Insert/Update Deals.", Constant.LOGGER_WEBSERVICE);
	    			if(!dao.insertDealCenter(RetadModel[i], dcConn, mod_user ))
	    				LogWriter.error("DealId : " + RetadModel[i].getDealID() +  " ==> " + 
										PropsUtils.getMessage(Constant.PROP_MESSAGE, ConstantMessage.ERR_INS_DEALS), Constant.LOGGER_WEBSERVICE);
	    			
					if (!dao.updateDealsCenter(RetadModel[i].getDealID(),
							RetadModel[i].getOutstdAmt(), 
							RetadModel[i].getDocType().toUpperCase(), 
							dcConn, mod_user, 
							RetadModel[i].getCifNumber(), RetadModel[i].getComments()))
						LogWriter.error("DealId : " + RetadModel[i].getDealID() +  " ==> " + 
										PropsUtils.getMessage(Constant.PROP_MESSAGE, ConstantMessage.ERR_UPD_DEALS), Constant.LOGGER_WEBSERVICE);
	    			
	    			
				} // End loop.
	
	    		// Prepare data from DealCenter by Ret-Ad Condition
	    		LogWriter.debug("Prepare select Deals.", Constant.LOGGER_WEBSERVICE);
				response = dao.getDealsFromInquire(
													(dealList.size() > 0) ? dealList.get(0) : "" 
													,cif_id
													,ccy
													,buy_sell
													,value_date
													,dcConn
												  );	    			    		
	    	}else{
	    		// Not found data on RET-AD.
	    		response = new wsInquiryResBody[0];
	    	}
		    		 	
    	}catch(Exception e){
    		throw new Exception();
    	}
    	
		return response;
    	
    }
    
    private wsInquiryResponse genereateErrorResponse(Connection dcConn, wsInquiryReqHeader reqHeader, String returnCode, String errorDesc) {
    	    
		wsInquiryResponse returnedResponse = null;
		
		wsInquiryResBody[] respBody = new wsInquiryResBody[0];
    	String res_time = commonUtils.formatDate(commonUtils.getCurrentDate(), commonUtils.ddmmyyyyhhmmsswithslash);
    	int NUM_OF_REC = 0;
    	String xmlResponse = "";
    	 
    	try{
	    	    	
    		// Case : Inquiry
    		wsInquiryResHeader h_inq = new wsInquiryResHeader(reqHeader.getServiceID(), reqHeader.getRequestID(),
    				reqHeader.getSystem(), returnCode, errorDesc, res_time, NUM_OF_REC);
	        
	      
	        returnedResponse = new wsInquiryResponse(h_inq,respBody);
	        
	       //--log response	 
	        xmlResponse = genResponseXML(h_inq, respBody);
	        LogWriter.info("=====XML Response : " + xmlResponse, Constant.LOGGER_WEBSERVICE);
	        LogWriter.info("=====Insert Log Response into table.=====", Constant.LOGGER_WEBSERVICE);		   			
			LogToDB.logResponse(dcConn, returnCode, errorDesc, respBody.length, "", "", ser_req_id);
			
    	}catch(Exception ex){
    		LogWriter.error(PropsUtils.getMessage(Constant.PROP_MESSAGE, ConstantMessage.ERR_EXCEPTION), Constant.LOGGER_WEBSERVICE);
    	}
		        
        return returnedResponse;
    }
    
    private wsInquiryResponse generateSuccessResponse(Connection dcConn, wsInquiryReqHeader reqHeader, wsInquiryResBody[] respBody) {
    	
		wsInquiryResponse returnedResponse = null;
		
        String respCode = ConstantMessage.INF_SUCCESS;
        String respDesc = PropsUtils.getMessage(Constant.PROP_MESSAGE, ConstantMessage.INF_SUCCESS);
        String res_time = commonUtils.formatDate(commonUtils.getCurrentDate(), commonUtils.ddmmyyyyhhmmsswithslash);
        String xmlResponse = "";
        
        try{      		
    		// Case : Inquiry
    		wsInquiryResHeader respHeader = new wsInquiryResHeader(reqHeader.getServiceID(), reqHeader.getRequestID(),
    				reqHeader.getSystem(), respCode, respDesc, res_time, respBody.length);
	        
	      
	        returnedResponse = new wsInquiryResponse(respHeader,respBody);
	        
	       //--log response	  
	        xmlResponse = genResponseXML(respHeader, respBody);
	        LogWriter.info("=====XML Response : " + xmlResponse, Constant.LOGGER_WEBSERVICE);
	        LogWriter.info("=====Insert Log Response into table.=====", Constant.LOGGER_WEBSERVICE);
			LogToDB.logResponse(dcConn, respCode, respDesc, respBody.length, "", "", ser_req_id);
      
        }catch(Exception e){
        	LogWriter.error(PropsUtils.getMessage(Constant.PROP_MESSAGE, ConstantMessage.ERR_EXCEPTION), Constant.LOGGER_WEBSERVICE);
        }
        
        return returnedResponse;
    }
 
   
 
    
    
}
